import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# 定义元胞自动机的尺寸
size = 30

# 初始化三维网格
grid = np.random.choice([0, 1], size=(size, size, size), p=[0.8, 0.2])

# 定义邻居的相对位置
neighbors = [(i, j, k) for i in [-1, 0, 1] for j in [-1, 0, 1] for k in [-1, 0,1] if not (i == 0 and j == 0 and k == 0)]

# 定义更新规则
def update(grid):
    new_grid = np.zeros_like(grid)
    for x in range(size):
        for y in range(size):
            for z in range(size):
                # 计算活跃邻居的数量
                active_neighbors = 0
                for dx, dy, dz in neighbors:
                    nx, ny, nz = x + dx, y + dy, z + dz
                    if 0 <= nx < size and 0 <= ny < size and 0 <= nz < size:
                        active_neighbors += grid[nx, ny, nz]
                
                # 应用规则
                if grid[x, y, z] == 1:
                    if active_neighbors < 2 or active_neighbors > 3:
                        new_grid[x, y, z] = 0
                    else:
                        new_grid[x, y, z] = 1
                else:
                    if active_neighbors == 3:
                        new_grid[x, y, z] = 1
    return new_grid
colors=np.append(np.arange(5,255,1),np.arange(255,5,-1))
# 可视化函数
def visualize(grid, step):
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111, projection='3d')
    ax.voxels(grid, color=(colors[step%len(colors)]/255,1,1),edgecolor='k',alpha=1)
    #ax.set_title(f'Step {step}')
    #print(len(view_angle))
    print(view_angles[step%len(view_angles)], view_angles[(step+1)%len(view_angles)])
    ax.view_init(elev=e_angles[step%len(e_angles)], azim=a_angles[(step)%len(a_angles)])
    ax.set_xticks([])
    ax.set_yticks([])
    ax.set_zticks([])
    plt.axis("off")
    plt.savefig("D:/3_bodies/live_game/3d_"+str(step)+".jpg")
    plt.show()
e_angles =np.append(np.arange(-45,45,3),np.arange(45,-45,-3))
a_angles=np.arange(-180,180,3)
#view_angles = [(elev, azim) for elev in angles for azim in angles]
print(view_angles)
# 运行元胞自动机并可视化
steps = 1000
for step in range(steps):
    visualize(grid, step)
    if step%10==0:
        grid = update(grid)